/* vim: set ts=2 et sw=2 cindent fo=qroca: */

package com.globant.google.mendoza.malbec;

import com.globant.google.mendoza.malbec.schema._2.MerchantCalculationCallback;
import com.globant.google.mendoza.malbec.schema._2.MerchantCalculationResults;
import com.globant.google.mendoza.malbec.schema._2.ObjectFactory;
import com.globant.google.mendoza.malbec.transport.NotificationFirerer;
import com.globant.google.mendoza.malbec.transport.Transport;

/** This class triggers the order state change notification to the order
 * listener.
 *
 * Instances of this class are created by the jaxb unmarshaller through the
 * NotificationObjectFactory.
 */
final class MerchantCalculationCallbackFirerer extends
    MerchantCalculationCallback implements NotificationFirerer {

  /** Fires a notification event to an order.
   *
   * This notification event is fired after the acknowledge is sent to checkout
   * server.
   *
   * @param transport The transport implementation that will be used by the
   * order.
   *
   * @param listener The order listener that listens to notification events.
   */
  public void notify(final Transport transport, final OrderListener
      listener) {
  }

  /** Fires a pre-notification event to an order.
   *
   * This notification is sent before the acknowledge is sent to checkout. This
   * is used to fire calculation events. If the object that receives this event
   * throws an exception, the acknowledge is not sent to checkout.
   *
   * @param transport The transport implementation that will be used by the
   * order.
   *
   * @param orderListener The order listener that listens to notification
   * events.
   *
   * @param calculationListener The calculation listener that listens to
   * merchant calculation events.
   *
   * @return Returns a JAXBElement representing the response to checkout. It
   * may be null, in which case it returns an acknowledge to checkout.
   */
  public Object preNotify(final Transport transport, final OrderListener
      orderListener, final CalculationListener calculationListener) {

    Object result = calculationListener.calculate(
        getBuyerId(), getShoppingCart(), getBuyerLanguage(), this);

    if (result instanceof MerchantCalculationResults) {
      MerchantCalculationResults results = (MerchantCalculationResults) result;
      ObjectFactory factory = new ObjectFactory();
      return factory.createMerchantCalculationResults(results);
    } else if (result instanceof String) {
      String stringResult = (String) result;
      return stringResult;
    } else {
      throw new RuntimeException(
          "Unexpected type received from calculationListener"
          + result.getClass());
    }
  }
}

